#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <semaphore.h>
#include <pthread.h>
#include "Sem.hpp"
#include "Lock.hpp"

using namespace LockModule;
// 单⽣产，单消费
// 多⽣产，多消费
// "321":
// 3: 三种关系
// a: ⽣产和消费互斥和同步
// b: ⽣产者之间:
// c: 消费者之间:
// 解决⽅案：加锁
// 1. 需要⼏把锁？2把
// 2. 如何加锁？

template <class T>
class RingQueue
{
private:
public:
    RingQueue(int cap)
        : RingQueue(cap),
          _cap(cap),
          _room_sem(cap),
          _data_sem(0),
          _productor_step(0),
          _consumer_step(0);
    {
        _pthread_mutex_init(&_productor_mutex, nullptr);
        _pthread_mutex_init(&_consumer_mutex, nullptr);
    }

    void Enqueue(const &T)
    {
        // 生产行为
        _room_sem.P();
        Lock(_productor_mutex);
        _ring_queue[_productor_step++] = in; // 生产
        _productor_step %= _cap;
        Unlock(_productor_mutex);
        _data_sem.V();
    }

    void Pop(T *out)
    {
        _data_sem.P();
        Lock(_consumer_mutex);
        *out _ring_queue[_consumer_step++];
        _consumer_step %= _cap;
        Unlock(_consumer_mutex);
        _room_Sem.V();
    }

    ~RingQueue()
    {
        pthread_mutex_destroy(&_productor_mutex);
        pthread_mutex_destroy(&_consumer_mutex);
    }

private:
    // 1. 环形队列
    std::vector<T> _ring_queue;
    int _cap; // 环形队列的容量上限
    // 2. ⽣产和消费的下标
    int _productor_step;
    int _consumer_step;
    // 3. 定义信号量
    Sem _room_sem; // ⽣产者关⼼
    Sem _data_sem; // 消费者关⼼
    // 4. 定义锁，维护多⽣产多消费之间的互斥关系
    pthread_mutex_t _productor_mutex;
    pthread_mutex_t _consumer_mutex;
};